package com.eliza.base.views.learn.graphics

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ShoppingCart
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableFloatState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.BlurredEdgeTreatment
import androidx.compose.ui.draw.blur
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.paint
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.ColorMatrix
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize
import coil.compose.AsyncImage
import com.eliza.base.R
import kotlin.math.roundToInt

object ImagesX {
    @Composable
    fun Show() {
        val remember = remember {
            mutableIntStateOf(0)
        }
        Button(onClick = { remember.intValue++ }) {
            Text(text = "Click TO Change${remember.intValue}")
        }
        when (remember.intValue % 4) {
            0 -> LoadImg()
            1 -> BitmapAndVector()
            2 -> IconX()
        }
    }

    @Composable
    private fun LoadImg() {
        Column {
            Text(text = "加载图片 painterResource")

            Image(
//              BitmapPainter 负责将位图绘制到屏幕
                painter = painterResource(id = R.drawable.ic_launcher),
                contentDescription = stringResource(id = R.string.app_name)
            )
            AsyncImage(
                model = "https://shouku123.com/UploadData/202103/photo/21033020371816991045_small300.png",
                contentDescription = "Translated description of what the image contains"
            )
        }
    }

    //光栅图像和矢量图像是最常见的两种图像格式
    @Composable
    private fun BitmapAndVector() {
        Text(text = "获取图片对象 ImageBitmap.imageResource")

        val imageBitmap = ImageBitmap.imageResource(R.drawable.ic_launcher)

//        VectorPainter 负责在屏幕上绘制 ImageVector。ImageVector 支持一部分 SVG 命令。
//        并非所有图像都能以矢量的形式表示（例如，您用相机拍摄的照片就无法转换为矢量）。
// 矢量图像: xml,svg等
        Image(
            painter = painterResource(id = R.drawable.ic_launcher),
            contentDescription = stringResource(id = R.string.app_name)
        )
        val imageVector = ImageVector.vectorResource(id = R.drawable.ic_android_black_24dp)
    }

    @Composable
    private fun IconX() {
        Text(text = "Icon使用 painterResource")

        Icon(
            painter = painterResource(R.drawable.ic_android_black_24dp),
            contentDescription = "Icon painterResource"
        )
        Icon(
            Icons.Rounded.ShoppingCart,
            contentDescription = "shopping_cart_content_desc"
        )
    }
}

object CustomizeX {


    @Composable
    fun Show() {
        val remember = remember {
            mutableIntStateOf(0)
        }
        Button(onClick = { remember.intValue++ }) {
            Text(text = "CustomizeX ${remember.intValue}")
        }
        when (remember.intValue % 6) {
            0 -> ContentScaleX()
            1 -> clipX()
            2 -> borderX()
            3 -> colorFilterX()
            4 -> edgeTreatmentX()
            5 -> customPainterX()
        }
    }

    /*  ContentScale.Fit：均匀缩放图片，并保持宽高比（默认）。如果内容小于指定大小，系统会放大图片以适应边界。	ContentScale.Fit 纵向	ContentScale.Fit 横向
        ContentScale.Crop：将图片居中裁剪到可用空间。	ContentScale.Crop 纵向	ContentScale.Crop 横向
        ContentScale.FillHeight：缩放来源图片，保持宽高比不变，使边界与目标高度匹配。	ContentScale.FillHeight 纵向	ContentScale.FillHeight 横向
        ContentScale.FillWidth：缩放来源图片，保持宽高比不变，使边界与目标宽度匹配。	ContentScale.FillWidth 纵向	ContentScale.FillWidth 横向
        ContentScale.FillBounds：以非均匀方式垂直和水平缩放内容，以填充目标边界。（注意：如果将图片放入与其宽高比不完全相符的容器中，则图片会失真）	ContentScale.FillBounds 纵向	ContentScale.FillBounds 横向
        ContentScale.Inside：缩放来源图片，使宽高保持在目标边界内。如果来源图片在两个维度上都小于或等于目标，则其行为类似于“None”。内容始终包含在边界内。如果内容小于边界，则不会应用缩放。	来源图片大于边界： ContentScale.Inside 纵向，来源图片大于边界 来源图片小于边界： ContentScale.Inside 纵向，来源图片小于边界	来源图片大于边界： ContentScale.Inside 横向，来源图片大于边界 来源图片小于边界： ContentScale.Inside 横向，来源图片小于边界
        ContentScale.None：不对来源图片应用任何缩放。如果内容小于目标边界，则不会缩放以适应相应区域。
     */
    @Composable
    private fun ContentScaleX() {
        val imageModifier = Modifier
            .size(150.dp)
            .border(BorderStroke(1.dp, Color.Black))
            .background(Color.Yellow)
        val imgContentScale: @Composable (
            contentScale: ContentScale,
            contentDescription: String
        ) -> Unit = { contentScale, contentDescription ->
            Image(
                painter = painterResource(id = R.drawable.ic_launcher),
                contentDescription = "ContentScale.Fit",
                contentScale = contentScale, // 默认
                modifier = imageModifier
            )
        }
        Column {

            imgContentScale(ContentScale.Fit, "Fit")
            imgContentScale(ContentScale.FillBounds, "FillBounds")
            imgContentScale(ContentScale.Crop, "Crop")

        }
    }

    // 扩展
    class SquashedOval : androidx.compose.ui.graphics.Shape {


        override fun createOutline(
            size: androidx.compose.ui.geometry.Size,
            layoutDirection: LayoutDirection,
            density: Density
        ): Outline {
            val path = Path().apply {
                // We create an Oval that starts at ¼ of the width, and ends at ¾ of the width of the container.
                addOval(
                    Rect(
                        left = size.width / 4f,
                        top = 0f,
                        right = size.width * 3 / 4f,
                        bottom = size.height
                    )
                )
            }
            return Outline.Generic(path = path)
        }
    }

    @Composable
    private fun clipX() {
        Row {
            val imgClip: @Composable (
                shape: androidx.compose.ui.graphics.Shape,
            ) -> Unit = { shape ->

                Image(
                    painter = painterResource(id = R.drawable.ic_launcher_round_bird),
                    contentDescription = "clipX",
                    contentScale = ContentScale.Crop,
                    modifier = Modifier
                        .size(200.dp)
                        .clip(shape)
                )
            }
            imgClip(CircleShape)//圆形
            imgClip(RoundedCornerShape(16.dp)) //圆角
            imgClip(SquashedOval()) //自定义
        }
    }

    @Composable
    private fun borderX() {
        val borderWidth = 4.dp
        Row {

            val imgBorder: @Composable (
                shape: androidx.compose.ui.graphics.Shape,
                brush: Brush
            ) -> Unit = { shape, brush ->
                Image(
                    painter = painterResource(id = R.drawable.ic_launcher_round_bird),
                    contentDescription = "clipX",
                    contentScale = ContentScale.Crop,
                    modifier = Modifier
                        .size(200.dp)
                        .border(
                            BorderStroke(borderWidth, brush),
                            shape
                        )
                        .clip(shape)
                        .aspectRatio(4 / 3f) //自动宽高

                )
            }
            //渐变色彩
            val rainbowColorsBrush = remember {
                Brush.sweepGradient(
                    listOf(
                        Color(0xFF9575CD),
                        Color(0xFFBA68C8),
                        Color(0xFFE57373),
                        Color(0xFFFFB74D),
                        Color(0xFFFFF176),
                        Color(0xFFAED581),
                        Color(0xFF4DD0E1),
                        Color(0xFF9575CD)
                    )
                )
            }
            // Brush Color
            imgBorder(CircleShape, rainbowColorsBrush)
        }
    }

    // 滤镜
    @Composable
    private fun colorFilterX() {
        val borderWidth = 4.dp
        val filter: @Composable (
            colorFilter: ColorFilter
        ) -> Unit = { colorFilter ->
            Image(
                painter = painterResource(id = R.drawable.ic_launcher),
//            为了确保应用可提供无障碍功能，请为屏幕上的视觉元素提供 contentDescription
                contentDescription = stringResource(id = R.string.app_auth),
                modifier = Modifier.size(100.dp),
                colorFilter = colorFilter
            )
        }
        //
        filter(ColorFilter.tint(Color.Gray, BlendMode.Color))
        filter(ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) }))
        //设置具体参数
        val contrast = 2f // 0f..10f (1 should be default)
        val brightness = -180f // -255f..255f (0 should be default)
        // 调整 Image 可组合项的对比度或亮度
        var colorMatrix = floatArrayOf(
            contrast, 0f, 0f, 0f, brightness,
            0f, contrast, 0f, 0f, brightness,
            0f, 0f, contrast, 0f, brightness,
            0f, 0f, 0f, 1f, 0f
        )
        filter(ColorFilter.colorMatrix(ColorMatrix(colorMatrix)))
        colorMatrix = floatArrayOf(
            -1f, 0f, 0f, 0f, 255f,
            0f, -1f, 0f, 0f, 255f,
            0f, 0f, -1f, 0f, 255f,
            0f, 0f, 0f, 1f, 0f
        )
        filter(ColorFilter.colorMatrix(ColorMatrix(colorMatrix)))
    }

    // 模糊
    @Composable
    private fun edgeTreatmentX() {
        val edgeTreatmentx: @Composable (
            edgeTreatment: BlurredEdgeTreatment
        ) -> Unit = { edgeTreatment ->
            Image(
                painter = painterResource(id = R.drawable.ic_launcher),
                contentDescription = stringResource(id = R.string.app_auth),
                Modifier
                    .size(100.dp)
                    .blur(
                        radiusX = 10.dp,
                        radiusY = 10.dp,
                        edgeTreatment = edgeTreatment
                    )
            )

        }
        //=======
        //对 Images 进行模糊处理时，建议使用 BlurredEdgeTreatment(Shape)
        // （而非 BlurredEdgeTreatment.Unbounded），因为后者用于对预计会在原始内容边界以外呈现的任意渲染进行模糊处理。
        // 图片很可能不会在内容边界以外呈现；而在对圆角矩形进行模糊处理时，可能需要这种不同的处理方式。
        edgeTreatmentx(BlurredEdgeTreatment(RoundedCornerShape(8.dp)))
        edgeTreatmentx(BlurredEdgeTreatment.Unbounded)


    }

    @Composable
    private fun customPainterX() {
        val rainbowImage = ImageBitmap.imageResource(id = R.drawable.ic_launcher)
        val dogImage = ImageBitmap.imageResource(id = R.drawable.bar_point)
        val customPainter = remember {
            OverlayImagePainter(dogImage, rainbowImage)
        }
        Image(
            painter = customPainter,
            contentDescription = "customPainterX",
            contentScale = ContentScale.Crop,
            modifier = Modifier.wrapContentSize()
        )
// 自定义 Painter 还可以与 Modifier.paint(customPainter) 搭配使用，以便将内容绘制到可组合项

        Box(
            modifier =
            Modifier
                .background(color = Color.Gray)
                .padding(30.dp)
                .background(color = Color.Yellow)
                .paint(customPainter)
        ) { /** intentionally empty **/ } //
// 故意留空
    }
}


class OverlayImagePainter constructor(
    private val image: ImageBitmap,
    private val imageOverlay: ImageBitmap,
    private val srcOffset: IntOffset = IntOffset.Zero,
    private val srcSize: IntSize = IntSize(image.width, image.height),
    private val overlaySize: IntSize = IntSize(imageOverlay.width, imageOverlay.height)
) : Painter() {

    private val size: IntSize = validateSize(srcOffset, srcSize)
    override fun DrawScope.onDraw() {
        // draw the first image without any blend mode
        drawImage(
            image,
            srcOffset,
            srcSize,
            dstSize = IntSize(
                this@onDraw.size.width.roundToInt(),
                this@onDraw.size.height.roundToInt()
            )
        )
        // draw the second image with an Overlay blend mode to blend the two together
        drawImage(
            imageOverlay,
            srcOffset,
            overlaySize,
            dstSize = IntSize(
                this@onDraw.size.width.roundToInt(),
                this@onDraw.size.height.roundToInt()
            ),
            blendMode = BlendMode.Overlay
        )
    }

    /**
     * Return the dimension of the underlying [ImageBitmap] as it's intrinsic width and height
     */
    override val intrinsicSize: Size get() = size.toSize()

    private fun validateSize(srcOffset: IntOffset, srcSize: IntSize): IntSize {
        require(
            srcOffset.x >= 0 &&
                    srcOffset.y >= 0 &&
                    srcSize.width >= 0 &&
                    srcSize.height >= 0 &&
                    srcSize.width <= image.width &&
                    srcSize.height <= image.height
        )
        return srcSize
    }
}